﻿using System;
using System.Collections.Generic;
using System.Linq;

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Rio.Framework.Localisation;
using NetBay.Core.BusinessEntities;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ServiceModel.DomainServices.Client;
using Rio.Framework.Pages.Context;

namespace Rio.Framework.Pages.ChildWindows
{
    public partial class ChoiceGroupWindow : GroupWindowBase
    {

        #region Properties

        /// <summary>
        /// Gets or sets the input value.
        /// </summary>
        /// <value>The input value.</value>
        public override string InputValue
        {
            get
            {
                if (GridUsersSelected.SelectedItems != null && GridUsersSelected.SelectedItems.Count > 0)
                {
                    string L_szSelectedGroups = String.Empty;
                    foreach (Group item in GridUsersSelected.SelectedItems)
                    {
                        if (L_szSelectedGroups.Equals(String.Empty))
                        {
                            L_szSelectedGroups = item.Name;
                        }
                        else
                        {
                            L_szSelectedGroups = L_szSelectedGroups + ";" + item.Name;
                        }
                    }

                    return L_szSelectedGroups;
                }
                else
                {
                    return String.Empty;
                }
            }
            set
            {
                AddedGroups.Clear();
                String[] L_oGroups = m_sGroupListToString.Split(new char[] { ';' });
                foreach (string str in L_oGroups)
                {
                    foreach (Group l_oGroup in GridUsersSelected.Items)
                    {
                        if (l_oGroup.Name.Equals(str))
                        {
                            AddedGroups.Add(l_oGroup);
                        }
                    }
                }

            }
        }

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ChoiceGroupWindow" /> class.
        /// </summary>
        public ChoiceGroupWindow()
            :base()
        {
            Initialize();
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="GroupFilterWindow" /> class.
        /// </summary>
        /// <param name="p_sGroupList">The P_S group list.</param>
        /// <param name="p_bGroupRestrict">The P_B group restrict.</param>
        public ChoiceGroupWindow(string p_sGroupList, bool p_bGroupRestrict = false)
            : base(p_sGroupList, p_bGroupRestrict)
        {
            Initialize();
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="GroupFilterWindow" /> class.
        /// </summary>
        /// <param name="p_oGroupList">The p_o group list.</param>
        /// <param name="p_bGroupRestrict">The P_B group restrict.</param>
        public ChoiceGroupWindow(List<Group> p_oGroupList, bool p_bGroupRestrict = false)
            : base(p_oGroupList, p_bGroupRestrict)
        {
            Initialize();
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="GroupFilterWindow" /> class.
        /// </summary>
        /// <param name="p_oGroupIdList">The p_o group id list.</param>
        /// <param name="p_bGroupRestrict">The P_B group restrict.</param>
        public ChoiceGroupWindow(List<long> p_oGroupIdList, bool p_bGroupRestrict = false)
            : base(p_oGroupIdList, p_bGroupRestrict)
        {
            Initialize();
        }

        #endregion

        #region Private functions

        /// <summary>
        /// Handles the KeyUp event of the MessageBoxChildWindow control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Input.KeyEventArgs" /> instance containing the event data.</param>
        private void MessageBoxChildWindow_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Escape)
            {
                DialogResult = false;
                this.Close();
            }
        }

        /// <summary>
        /// Inits the label.
        /// </summary>
        private void InitLabel()
        {
            OkButton.Content = Resx.GetLabel(ResxCommon.OK);
            CancelButton.Content = Resx.GetLabel(ResxCommon.CANCEL);
            UsersAvaillableTextBlock.Text = Resx.GetLabel((ResxChoiceGroupWindow.USERS_AVAILABLE));
        }

        /// <summary>
        /// This method Get the group list and bind it to the grid
        /// </summary>
        /// <returns>A list of group</returns>
        private void GetGroupList()
        {
            GridUsersAvailable.IsBusy = true;

            var GroupList_Query = GlobalWebContext.BusinessEntitiesDomainContext.GetAllGroupQuery();
            GlobalWebContext.BusinessEntitiesDomainContext.Load(GroupList_Query, OnGetGroupListQueryCallback, null);
            this.IsEnabled = false;
        }

        /// <summary>
        /// Call back method binding the list of group to the Grid
        /// </summary>
        /// <param name="result">List of group</param>
        private void OnGetGroupListQueryCallback(LoadOperation<Group> result)
        {
            this.IsEnabled = true;
            List<Group> l_oGroups = new List<Group>(result.Entities);
            if ((l_oGroups != null) && (l_oGroups.Count > 0))
            {
                //Init values list
                m_oGroupList = l_oGroups;
                String[] l_oGroupString = m_sGroupListToString.Split(new char[] { ';' });
                List<Group> l_oMailTo = new List<Group>();

                //Get the group based on the Mailto group name
                foreach (string str in l_oGroupString)
                {
                    foreach (Group l_oGroup in l_oGroups)
                    {
                        if (l_oGroup.Name.Equals(str))
                        {
                            l_oMailTo.Add(l_oGroup);
                        }
                    }
                }

                if (_groupRestrict)
                {
                    _displayedGroupList = l_oMailTo;
                }
                else
                {
                    _displayedGroupList = l_oGroups;
                }

                AvailableGroups = new ObservableCollection<Group>(_displayedGroupList);
                if (!String.IsNullOrWhiteSpace(m_sGroupListToString))
                {
                    //Check the selected group based on the Mailto group name
                    foreach (string str in l_oGroupString)
                    {
                        foreach (Group l_oGroup in AvailableGroups)
                        {
                            if (l_oGroup.Name.Equals(str))
                            {
                                AddedGroups.Add(l_oGroup);
                                break;
                            }
                        }
                    }
                }
                else if (_groupListId != null && _groupListId.Count > 0)
                {
                    foreach (long id in _groupListId)
                    {
                        foreach (Group l_oGroup in AvailableGroups)
                        {
                            if (l_oGroup.Identifier == id)
                            {
                                AddedGroups.Add(l_oGroup);
                                break;
                            }
                        }
                    }
                }
            }

            GridUsersAvailable.IsBusy = false;
            GridUsersAvailable.Focus();
        }

        /// <summary>
        /// Handles the Click event of the OkButton control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs" /> instance containing the event data.</param>
        private void OkButton_Click(object sender, RoutedEventArgs e)
        {
            m_szSelectedItems = new List<Group>();
            foreach (Group l_oGroup in AddedGroups)
            {
                m_szSelectedItems.Add(l_oGroup);
            }

            this.DialogResult = true;
            this.Close();
        }

        /// <summary>
        /// Handles the Click event of the CancelButton control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs" /> instance containing the event data.</param>
        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            DialogResult = false;
            this.Close();
        }

        /// <summary>
        /// Handles the Loaded event of the ChoiceGroupWindow control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs" /> instance containing the event data.</param>
        private void ChoiceGroupWindow_Loaded(object sender, RoutedEventArgs e)
        {
            GetGroupList();
        }

        /// <summary>
        /// Handles the Click event of the GoToRigthButton control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs" /> instance containing the event data.</param>
        private void GoToRigthButton_Click(object sender, RoutedEventArgs e)
        {
            foreach (Group item in GridUsersAvailable.SelectedItems)
            {
                if (!AddedGroups.Contains(item))
                {
                    AddedGroups.Add(item);
                }
            }
            GridUsersAvailable.UnselectAll();
        }

        /// <summary>
        /// Handles the Click event of the GoToLeftButton control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs" /> instance containing the event data.</param>
        private void GoToLeftButton_Click(object sender, RoutedEventArgs e)
        {
            if (GridUsersSelected.SelectedItems != null && GridUsersSelected.SelectedItems.Count > 0)
            {
                var items = GridUsersSelected.SelectedItems;
                for (int i = 0; i < items.Count; i++)
                {
                    GridUsersSelected.Items.RemoveAt(i);
                }
            }
        }

        /// <summary>
        /// Handles the Click event of the UpButton control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs" /> instance containing the event data.</param>
        private void UpButton_Click(object sender, RoutedEventArgs e)
        {
            if (GridUsersSelected.SelectedItems != null && GridUsersSelected.SelectedItems.Count > 0)
            {

                var items = GridUsersSelected.SelectedItems ;
                for (int i = 0; i < items.Count; i++)
                {
                    Group currentItem = (Group)items[i];
                    int currentIndex = AddedGroups.IndexOf(currentItem);
                    int newIndex = currentIndex > 0 ? currentIndex - 1 : AddedGroups.Count - 1;

                    AddedGroups.RemoveAt(currentIndex);
                    AddedGroups.Insert(newIndex, currentItem);

                    GridUsersSelected.SelectedItem = currentItem;
                }
            }
        }

        /// <summary>
        /// Handles the Click event of the DownButton control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs" /> instance containing the event data.</param>
        private void DownButton_Click(object sender, RoutedEventArgs e)
        {

            if (GridUsersSelected.SelectedItems != null && GridUsersSelected.SelectedItems.Count > 0)
            {

                var items = GridUsersSelected.SelectedItems;
                for (int i = 0; i < items.Count; i++)
                {
                    Group currentItem = (Group)items[i];
                    int currentIndex = AddedGroups.IndexOf(currentItem);
                    int newIndex = currentIndex < AddedGroups.Count - 1 ? currentIndex + 1 : 0;

                    AddedGroups.RemoveAt(currentIndex);
                    AddedGroups.Insert(newIndex, currentItem);

                    GridUsersSelected.SelectedItem = currentItem;
                }
            }
        }

        /// <summary>
        /// Inits this instance.
        /// </summary>
        private void Initialize()
        {
            InitializeComponent();

            this.Loaded += ChoiceGroupWindow_Loaded;

            InitLabel();
        }

        /// <summary>
        /// Handles the TextChanged event of the FilterValue control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Controls.TextChangedEventArgs" /> instance containing the event data.</param>
        private void FilterValue_TextChanged(object sender, TextChangedEventArgs e)
        {
            List<Group> l_oGroupList = new List<Group>(FilterItems(TextBoxStartingWith.Text));
            List<Group> l_oAddedGroup = new List<Group>();
            foreach (Group l_ogrp in GridUsersAvailable.SelectedItems)
            {
                if (!l_oGroupList.Contains(l_ogrp))
                {
                    l_oGroupList.Add(l_ogrp);

                }
                l_oAddedGroup.Add(l_ogrp);
            }

            AvailableGroups = new ObservableCollection<Group>(l_oGroupList);

            foreach (Group l_oAddedGrp2 in l_oAddedGroup)
            {
                GridUsersAvailable.SelectedItems.Add(l_oAddedGrp2);
            }

            this.TextBoxStartingWith.Focus();
        }

        #endregion

    }
}
